.equ SYS_MOD,0x1f
.equ IRQ_MOD,0x12
.equ FIQ_MOD,0x11
.equ ABT_MOD,0x17
.equ UND_MOD,0x1b
 
.equ DISABLE_IRQ,0x80
.equ DISBALE_FIQ,0x40
 
.macro CHANGE_TO_SYS
	msr cpsr_c,#(DISABLE_IRQ | DISBALE_FIQ | SYS_MOD)
.endm
 
.macro CHANGE_TO_IRQ
	msr cpsr_c,#(DISABLE_IRQ | DISBALE_FIQ | IRQ_MOD)
.endm
 
.global __vector_undefined
.global __vector_swi
.global __vector_prefetch_abort
.global __vector_data_abort
.global __vector_reserved
.global __vector_irq
.global __vector_fiq
 
.extern handle_abnormal_undefined
.extern handle_abnormal_swi
.extern os_system_call
.extern handle_abnormal_prefetch
.extern handle_abnormal_data
.extern handle_abnormal_reserved
.extern __common_schedule
 
.text
.code 32
 
__vector_undefined:
	b handle_abnormal_undefined
	nop
 
__vector_swi:
	str lr,[r13,#-4]		@保存用户模式swi指令后一指令地址
	mrs r0,spsr			@取用户模式程序状态
	str r0,[r13,#-8]		@保存用户模式程序状态
	mov r0,r13			@取软件中断异常状态(管理模式)栈指针
	CHANGE_TO_SYS			@切换到系统模式(内核态)
	stmfd r13!,{r0}		@把管理模式栈指针压入系统模式栈
	ldr r0,[r0,#-4]		@取用户模式swi指令后一指令地址
	sub r0,r0,#4			@取用户模式swi指令地址
	ldr r0,[r0]			@取用户模式swi指令
	bic r0,r0,#0xff000000	@取swi指令的后24位(系统调用类型号)
	bl os_system_call		@系统调用
	ldmfd r13!,{r1}		@管理模式栈指针出栈到r1
	ldr r2,[r1,#-8]		@取用户模式程序状态
	msr cpsr,r2			@切换为用户模式程序状态
	ldr pc,[r1,#-4]		@取用户模式swi指令后一指令地址
	nop
 
__vector_prefetch_abort:
	b handle_abnormal_prefetch
	nop
 
__vector_data_abort:
	b handle_abnormal_data
	nop
 
__vector_reserved:
	b handle_abnormal_reserved
	nop
 
__vector_irq:
	sub r14,r14,#4		@取被中断进程的返回地址
	stmfd r13!,{r0}		@r0压入中断模式栈,被中断进程的args
	stmfd r13!,{r1-r3}	@r3-r1压入中断模式栈
	mov r2,#0xca000000	@取中断控制器地址
	add r1,r2,#0x10
	ldr r0,[r1]
	ldr r3,[r2]
	orr r3,r3,r1
	str r3,[r2]
	str r0,[r1]
	ldmfd r13!,{r1-r3}
	mov r0,r14
	CHANGE_TO_SYS
	stmfd r13!,{r0}
	stmfd r13!,{r14}
	CHANGE_TO_IRQ
	ldmfd r13!,{r0}
	ldr r14,=__asm_schedule
	stmfd r13!,{r14}
	ldmfd r13!,{pc}^
__asm_schedule:
	stmfd r13!,{r0-r12}
	mrs	r1, cpsr
	stmfd r13!,{r1}
	mov	r1,sp
	bic	r1,#0xff0
	bic r1,#0xf
	mov r0,sp
	str r0,[r1]
	bl __common_schedule
	ldr sp,[r0]
	ldmfd r13!,{r1}
	msr cpsr_cxsf,r1
	ldmfd r13!,{r0-r12,r14,pc}
	nop
 
__vector_fiq:
	nop
 
@ my__vector_irq:
@ 	sub lr,lr,#0x4
@ 	stmfd sp!,{lr}
@ 	bl common_irq_handler
@ 	mrs lr,spsr
@ 	msr cpsr_c,lr
@ 	ldmfd sp!,{lr}
@ 	mov pc,lr
 
@ book__vector_irq:				@书里中断异常的复杂处理程序
@ 	sub r14,r14,#0x4
@ 	stmfd r13!,{r14}
@ 	mrs r14,spsr
@ 	stmfd r13!,{r14}
@ 	CHANGE_TO_SVC
@ 	stmfd r13!,{r0,r1,r2,r3}
@ 	bl common_irq_handler
@ 	ldmfd r13!,{r0,r1,r2,r3}
@ 	CHANGE_TO_IRQ
@ 	ldmfd r13!,{r14}
@ 	msr spsr,r14
@ 	ldmfd r13!,{pc}^
 
@ book__vector_irq:					@书里优秀的中断异常处理程序
@ 	sub r14,r14,#0x4
@ 	str r14,[r13,#-0x4]
@ 	mrs r14,spsr
@ 	str r14,[r13,#-0x8]
@ 	str r0,[r13,#-0xc]
@ 	mov r0,r13
@ 	CHANGE_TO_SVC
@ 	str r14,[r13,#-0x8]!
@ 	ldr r14,[r0,#-0x4]
@ 	str r14,[r13,#-0x4]
@ 	ldr r14,[r0,#-0x8]
@ 	ldr r0,[r0,#-0xc]
@ 	stmdb r13!,{r0-r3,r14}
@ 	bl common_irq_handler
@ 	ldmia r13!,{r0-r3,r14}
@ 	msr spsr,r14
@ 	ldmfd r13!,{r14,pc}^
 
@ my__vector_swi:			@用以实现系统调用的软件中断异常处理程序
	@ str lr,[r13,#-4]		@保存用户模式swi指令后一指令地址
	@ mrs r0,spsr			@取用户模式程序状态
	@ str r0,[r13,#-8]		@保存用户模式程序状态
	@ mov r0,r13			@取软件中断异常状态(管理模式)栈指针
	@ CHANGE_TO_SYS			@切换到系统模式(内核态)
	@ stmfd r13!,{r0}		@把管理模式栈指针压入系统模式栈
	@ ldr r0,[r0,#-4]		@取用户模式swi指令后一指令地址
	@ sub r0,r0,#4			@取用户模式swi指令地址
	@ ldr r0,[r0]			@取用户模式swi指令
	@ bic r0,r0,#0xff000000	@取swi指令的后24位(系统调用类型号)
	@ bl os_system_call		@系统调用
	@ ldmfd r13!,{r1}		@管理模式栈指针出栈到r1
	@ ldr r2,[r1,#-8]		@取用户模式程序状态
	@ msr cpsr,r2			@切换为用户模式程序状态
	@ ldr pc,[r1,#-4]		@取用户模式swi指令后一指令地址 
 
@ book_vector_irq:		@书里实现进程调度的中断异常处理程序
@ 	sub r14,r14,#4		@取被中断进程的返回地址
@ 	stmfd r13!,{r0}		@r0压入中断模式栈,被中断进程的args
@ 	stmfd r13!,{r1-r3}	@r3-r1压入中断模式栈
 
@ 	mov r2,#0xca000000	@取中断控制器地址
@ 	add r1,r2,#0x10
@ 	ldr r0,[r1]
@ 	ldr r3,[r2]
@ 	orr r3,r3,r1
@ 	str r3,[r2]
@ 	str r0,[r1]
 
@ 	ldmfd r13!,{r1-r3}
@ 	mov r0,r14
@ 	CHANGE_TO_SYS
@ 	stmfd r13!,{r0}
@ 	stmfd r13!,{r14}
@ 	CHANGE_TO_IRQ
@ 	ldmfd r13!,{r0}
@ 	ldr r14,=__asm_schedule
@ 	stmfd r13!,{r14}
@ 	ldmfd r13!,{pc}^
 
@ __asm_schedule:
@ 	stmfd r13!,{r0-r12}
@ 	mrs	r1, cpsr
@ 	stmfd r13!,{r1}
 
@ 	mov	r1,sp
@ 	bic	r1,#0xff0
@ 	bic r1,#0xf
@ 	mov r0,sp
@ 	str r0,[r1]
 
@ 	bl __common_schedule
@ 	ldr sp,[r0]
@ 	ldmfd r13!,{r1}
@ 	msr cpsr_cxsf,r1
@ 	ldmfd r13!,{r0-r12,r14,pc}